﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Maltose.Data
{
    /// <summary>
    /// 对SqlSugar扩展
    /// </summary>
    public class SqlSugarService : DapperService
    {


        /// <summary>
        /// 对SqlSugar扩展
        /// </summary>
        /// <param name="connectionString">连接字符串</param>
        public SqlSugarService(string connectionString) : base(connectionString) { }

        /// <summary>
        /// 对SqlSugar扩展
        /// </summary>
        /// <param name="dataBase">数据库版本选择</param>
        public SqlSugarService(DataBase dataBase) : base(dataBase) { }


        #region 获取列表数据

        /// <summary>
        /// 获取数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public List<T> List<T>() where T : class, new()
        {
            return DbContext.Queryable<T>().ToList();
        }

        /// <summary>
        /// 异步获取数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Task<List<T>> ListAsync<T>() where T : class, new()
        {
            return DbContext.Queryable<T>().ToListAsync();
        }

        /// <summary>
        /// 获取带条件的数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public List<T> List<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Queryable<T>().Where(where).ToList();
        }

        /// <summary>
        /// 异步获取带条件的数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public Task<List<T>> ListAsync<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Queryable<T>().Where(where).ToListAsync();
        }

        #endregion

        #region 获取单个数据

        /// <summary>
        /// 获取单个数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T Single<T>() where T : class, new()
        {
            return DbContext.Queryable<T>().First();
        }

        /// <summary>
        /// 异步获取单个数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Task<T> SingleAsync<T>() where T : class, new()
        {
            return DbContext.Queryable<T>().FirstAsync();
        }

        /// <summary>
        /// 获取单个数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public T Single<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Queryable<T>().Where(where).Single();
        }

        /// <summary>
        /// 异步获取单个数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public Task<T> SingleAsync<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Queryable<T>().Where(where).SingleAsync();
        }

        #endregion

        #region 添加

        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Insert<T>(T entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).IgnoreColumns(true).ExecuteCommand();
        }

        /// <summary>
        /// 异步添加一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<int> InsertAsync<T>(T entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).IgnoreColumns(true).ExecuteCommandAsync();
        }


        /// <summary>
        /// 添加一条数据 获取当前 自增列(INT)类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int InsertGetId<T>(T entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).IgnoreColumns(true).ExecuteReturnIdentity();
        }

        /// <summary>
        /// 添加一条数据 获取当前 自增列(INT)类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<int> InsertGetIdAsync<T>(T entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).IgnoreColumns(true).ExecuteReturnIdentityAsync();
        }

        /// <summary>
        /// 添加一条数据 获取当前 自增列(BIGINT)类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long InsertGetBigId<T>(T entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).IgnoreColumns(true).ExecuteReturnBigIdentity();
        }

        /// <summary>
        /// 添加一条数据 获取当前 自增列(BIGINT)类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<long> InsertGetBigIdAsync<T>(T entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).IgnoreColumns(true).ExecuteReturnBigIdentityAsync();
        }

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int InsertRange<T>(List<T> entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).ExecuteCommand();
        }

        /// <summary>
        /// 异步添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<int> InsertRangeAsync<T>(List<T> entity) where T : class, new()
        {
            return DbContext.Insertable<T>(entity).ExecuteCommandAsync();
        }

        #endregion

        #region 修改

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="where">条件</param>
        /// <returns></returns>
        public int Update<T>(T entity, Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Updateable<T>(entity).IgnoreColumns(true).Where(where).ExecuteCommand();
        }

        /// <summary>
        /// 异步修改数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="where">条件</param>
        /// <returns></returns>
        public Task<int> UpdateAsync<T>(T entity, Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Updateable<T>(entity).IgnoreColumns(true).Where(where).ExecuteCommandAsync();
        }

        /// <summary>
        /// 批量修改 主键为条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int UpdateRange<T>(List<T> entity) where T : class, new()
        {
            return DbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommand();
        }

        /// <summary>
        /// 批量修改 主键为条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<int> UpdateRangeAsync<T>(List<T> entity) where T : class, new()
        {
            return DbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandAsync();
        }

        #endregion

        #region 删除

        /// <summary>
        /// 异步删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public int Delete<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Deleteable<T>().Where(where).ExecuteCommand();
        }

        /// <summary>
        /// 异步删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public Task<int> DeleteAsync<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Deleteable<T>().Where(where).ExecuteCommandAsync();
        }

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public int DeleteById<T>(T id) where T : class, new()
        {
            return DbContext.Deleteable<T>().In(id).ExecuteCommand();
        }

        /// <summary>
        /// 根据主键 异步删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public Task<int> DeleteByIdAsync<T>(T id) where T : class, new()
        {
            return DbContext.Deleteable<T>().In(id).ExecuteCommandAsync();
        }

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ids"></param>
        /// <returns></returns>
        public int DeleteById<T>(T[] ids) where T : class, new()
        {
            return DbContext.Deleteable<T>().In(ids).ExecuteCommand();
        }

        /// <summary>
        /// 根据主键异步删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ids"></param>
        /// <returns></returns>
        public Task<int> DeleteByIdAsync<T>(T[] ids) where T : class, new()
        {
            return DbContext.Deleteable<T>().In(ids).ExecuteCommandAsync();
        }

        #endregion

        #region 获取数据量

        /// <summary>
        /// 获取条数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public int Count<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Queryable<T>().Where(where).Count();
        }

        /// <summary>
        /// 获取条数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public Task<int> CountAsync<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return DbContext.Queryable<T>().Where(where).CountAsync();
        }

        #endregion
    }
}
